﻿using System.Diagnostics.CodeAnalysis;
using System.IO;
using Communication.DataReceivedEvent;
using Communication.DataReceivedEvent.Can;
using Communication.DataReceivedEvent.Can.Itekon;
using Communication.DataReceivedEvent.COM;
using Microsoft.Extensions.Logging;

namespace Communication;

/// <summary>
///     数据接收事件工厂类，用于根据不同的设备类型创建对应的数据接收事件实例
/// </summary>
/// <param name="factory">日志记录器工厂，用于创建日志记录器</param>
public class DataReceivedEventFactory(ILoggerFactory factory)
{
    /// <summary>
    ///     根据提供的数据接收事件信息创建对应的数据接收事件实例
    /// </summary>
    /// <param name="info">数据接收事件信息，包含设备类型和具体配置</param>
    /// <param name="stream">输出参数，创建成功时返回对应的数据接收事件实例</param>
    /// <returns>创建成功返回true，否则返回false</returns>
    public bool Creation(IDataReceivedEventInfo info, [NotNullWhen(true)] out IDataReceivedEvent? stream)
    {
        stream = null;
        // 创建针对特定类型的日志记录器
        var logger = factory.CreateLogger(Path.Combine(nameof(IDataReceivedEvent), info.ToString(null, null)));
        // 根据设备类型进行相应的处理
        switch (info.Type)
        {
            case DataReceivedEventDevice.Can:
                // 如果是CAN设备类型，且信息为CanInfo类型，则创建CAN设备事件
                if (info is CanInfo canInfo) return CreationCan(canInfo, logger, out stream);
                break;
            case DataReceivedEventDevice.Com:
                // 如果是串口设备类型，且信息为SerialPortEventInfo类型，则创建串口设备事件
                if (info is SerialPortEventInfo comInfo) return CreationCom(comInfo, logger, out stream);
                break;
            default:
            case DataReceivedEventDevice.None:
                // 默认情况或未知设备类型，不做处理
                break;
        }

        // 如果没有匹配的设备类型，返回false
        return false;
    }

    /// <summary>
    ///     创建CAN设备数据接收事件实例
    /// </summary>
    /// <param name="info">CAN设备信息</param>
    /// <param name="logger">日志记录器</param>
    /// <param name="stream">输出参数，创建成功时返回CAN设备事件实例</param>
    /// <returns>创建成功返回true，否则返回false</returns>
    private static bool CreationCan(CanInfo info, ILogger logger,
        [NotNullWhen(true)] out IDataReceivedEvent? stream)
    {
        stream = null;
        // 根据具体的CAN设备类型创建对应的事件实例
        switch (info.Device)
        {
            case DeviceType.UsbCan2I:
                // 创建 Itekon 类型的CAN设备事件实例
                stream = new Itekon(info, logger);
                return true;
            default:
                // 不支持的CAN设备类型，返回false
                return false;
        }
    }

    /// <summary>
    ///     创建串口设备数据接收事件实例
    /// </summary>
    /// <param name="info">串口设备信息</param>
    /// <param name="logger">日志记录器</param>
    /// <param name="stream">输出参数，返回串口设备事件实例</param>
    /// <returns>创建成功返回true</returns>
    private static bool CreationCom(SerialPortEventInfo info, ILogger logger,
        [NotNullWhen(true)] out IDataReceivedEvent? stream)
    {
        // 创建SerialPortEvent类型的串口设备事件实例
        stream = new SerialPortEvent(info, logger);
        return true;
    }
}